package nba2kmodtool.filedesc;

import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;

import nba2kmodtool.util.ByteFileReader;

class N2kIffFileModelImporter {

	private static final boolean IS_DEBUG = BaseIffFile.IS_DEBUG;

	protected BaseIffFile iff;
	protected File file;

	protected N2kIffFileModelImporter(BaseIffFile iff) {
		this.iff = iff;
		this.file = iff.file;
	}

	public boolean importIffModel(BaseIffFile impiff, N2kPackageFile imppack, int impindex, N2k3DModelPart model)
			throws IOException {
		ByteFileReader in = null;
		ByteFileReader io = null;
		try {
			N2k3DModelPart impm = imppack.getModels()[impindex];
			int impPartNum = impm.childNum;
			int orgPartNum = model.childNum;
			int impVertexNum = impm.vertexNum;
			int orgVertexNum = model.vertexNum;
			int faceDataSize = impm.faceDataSize;
			int orgFaceNum = model.faceDataSize;
			int impPerVertexSize = impm.perVertexSize;
			int impPerUVSize = impm.perUVNSize;
			int orgPerVertexSize = model.perVertexSize;
			int orgPerUVSize = model.perUVNSize;
			if (impVertexNum > orgVertexNum || faceDataSize > orgFaceNum || impPerUVSize != orgPerUVSize
					|| impPerVertexSize != orgPerVertexSize) {
				throw new IOException(
						String.format(
								"Model Not Match:\nsource:\nvertex: %d, %d, %d; faceData: %d\nimport:\nvertex: %d, %d, %d; faceData: %d\n",
								orgVertexNum, orgPerVertexSize, orgPerUVSize, orgFaceNum, impVertexNum,
								impPerVertexSize, impPerUVSize, faceDataSize));
			}
			in = new ByteFileReader(impiff.file, "r");
			io = new ByteFileReader(file, "rw");
			//fix child definition data
			io.seek(model.childDefAddr);
			int childDefNum = Math.min(impPartNum, orgPartNum);
			int defSize = model.childDefSize;
			for (int i = 0; i < childDefNum; i++) {
				N2k3DChildModelPart child = impm.childParts[i];
				io.skipBytes(0x04);
				io.writeIntBigEndin(child.index);
				io.writeIntBigEndin(child.indicesNum0);
				io.writeIntBigEndin(child.indicesNum1);
				io.skipBytes(0x04);
				io.writeIntBigEndin(child.vertStart);
				io.writeIntBigEndin(child.vertNum);
				io.skipBytes(defSize - 0x1C);
			}
			for (int i = 0; i < (orgPartNum - childDefNum); i++) {
				io.skipBytes(0x04);
				io.writeIntBigEndin(0x00);
				io.writeIntBigEndin(0x00);
				io.writeIntBigEndin(0x00);
				io.skipBytes(0x04);
				io.writeIntBigEndin(0x00);
				io.writeIntBigEndin(0x00);
				io.skipBytes(defSize - 0x1C);
			}
			//import vertexes data
			in.seek(impm.vertexDataStart);
			ByteBuffer buffer = ByteBuffer.allocate(impVertexNum * impPerVertexSize);
			in.read(buffer.array());
			buffer.rewind();
			io.seek(model.vertexDataStart);
			io.write(buffer.array());
			if (impPerUVSize > 0) {
				in.seek(impm.uvnDataStart);
				buffer = ByteBuffer.allocate(impVertexNum * impPerUVSize);
				in.read(buffer.array());
				buffer.rewind();
				io.seek(model.uvnDataStart);
				io.write(buffer.array());
			}
			//import face data
			int restDataSize = model.faceDataSize - faceDataSize;
			in.seek(impm.faceDataStart);
			io.seek(model.faceDataStart);
			buffer = ByteBuffer.allocate(faceDataSize * 2);
			in.read(buffer.array());
			buffer.rewind();
			io.write(buffer.array());
			byte[] zero = { 0x00, 0x00 };
			if (restDataSize > 0) {
				for (int i = 0; i < restDataSize; i++) {
					io.write(zero);
				}
			}
			in.close();
			io.close();
			return true;
		} finally {
			if (in != null) {
				in.close();
			}
			if (io != null) {
				io.close();
			}
		}
	}
}
